package com.baogu.factoryjob.service.impl;

import com.baogu.factoryjob.util.DateUtils;
import com.baogu.model.job.JobManage;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class TaskServiceImpl {
    private Logger logger = LogManager.getLogger(getClass());
    @Autowired
    private Scheduler scheduler;


    /**
     * 所有任务列表
     * 2016年10月9日上午11:16:59
     */
    public List<JobManage> list() throws SchedulerException {
        List<JobManage> list = new ArrayList<JobManage>();
        for(String groupJob: scheduler.getJobGroupNames()){
            for(JobKey jobKey: scheduler.getJobKeys(GroupMatcher.<JobKey>groupEquals(groupJob))){
                List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
                for (Trigger trigger: triggers) {
                    String cronExpression = "";
                    if (trigger instanceof CronTrigger) {
                        CronTrigger cronTrigger = (CronTrigger) trigger;
                        cronExpression = cronTrigger.getCronExpression();
                    }
                    JobManage info = new JobManage();
                    info.setId(jobKey.getName());
                    info.setExpression(cronExpression);
                    list.add(info);
                }
            }
        }
        return list;
    }

    /**
     * 所有任务列表--map
     * 2016年10月9日上午11:16:59
     */
    public Map<String,JobManage> getMap() throws SchedulerException {
        List<JobManage> list = this.list();
        Map<String,JobManage> map = new HashMap<>();
        for (JobManage jobManage:list){
            map.put(jobManage.getId(),jobManage);
        }
        return map;
    }



    /**
     * 保存定时任务
     * 2016年10月9日上午11:30:40
     */
    public void addJob(JobManage jobManage) throws SchedulerException, ClassNotFoundException {
        String jobName = jobManage.getId(),
                jobClass = jobManage.getJobclass(),
                jobGroup = "default",
                cronExpression = jobManage.getExpression(),
                jobDescription = jobManage.getJobname(),
                createTime = DateUtils.yyyyMMddHHmmssSSS();
        if (checkExists(jobName, jobGroup)) {
            logger.info("===> AddJob fail, job already exist, jobGroup:"+jobGroup+", jobName:"+jobName+"");
        }
        TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
        CronScheduleBuilder schedBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();
        CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withDescription(createTime).withSchedule(schedBuilder).build();
        Class<? extends Job> clazz = (Class<? extends Job>)Class.forName(jobClass);
        JobDetail jobDetail = JobBuilder.newJob(clazz).withIdentity(jobKey).withDescription(jobDescription).build();
        scheduler.scheduleJob(jobDetail, trigger);
    }

    /**
     * 修改定时任务
     * 2016年10月9日下午2:20:07
     */
    public void edit(JobManage jobManage) throws SchedulerException {
        String jobName = jobManage.getId(),
                jobGroup = "default",
                cronExpression = jobManage.getExpression(),
                jobDescription = jobManage.getJobname(),
                createTime = DateUtils.yyyyMMddHHmmssSSS();
        if (!checkExists(jobName, jobGroup)) {
            logger.info("===> job update fail, job already exist, jobGroup:"+jobGroup+", jobName:"+jobName+"");
        }
        TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
        JobKey jobKey = new JobKey(jobName, jobGroup);
        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();
        CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withDescription(createTime).withSchedule(cronScheduleBuilder).build();
        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
        jobDetail.getJobBuilder().withDescription(jobDescription);
        HashSet<Trigger> triggerSet = new HashSet<>();
        triggerSet.add(cronTrigger);
        scheduler.scheduleJob(jobDetail, triggerSet, true);
    }

    /**
     * 删除定时任务
     * @param jobName
     * @param jobGroup
     * 2016年10月9日下午1:51:12
     */
    public void delete(String jobName, String jobGroup) throws SchedulerException {
        TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
        if (checkExists(jobName, jobGroup)) {
            scheduler.pauseTrigger(triggerKey);
            scheduler.unscheduleJob(triggerKey);
        }
    }

    /**
     * 暂停定时任务
     * @param jobName
     * @param jobGroup
     * 2016年10月10日上午9:40:19
     */
    public void pause(String jobName, String jobGroup) throws SchedulerException {
        TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
        if (checkExists(jobName, jobGroup)) {
            scheduler.pauseTrigger(triggerKey);
        }
    }

    /**
     * 重新开始任务
     * @param jobName
     * @param jobGroup
     * 2016年10月10日上午9:40:58
     */
    public void resume(String jobName, String jobGroup) throws SchedulerException {
        TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
        if (checkExists(jobName, jobGroup)) {
            scheduler.resumeTrigger(triggerKey);
        }
    }

    /**
     * 验证是否存在
     * @param jobName
     * @param jobGroup
     * @throws SchedulerException
     * 2016年10月8日下午5:30:43
     */
    private boolean checkExists(String jobName, String jobGroup) throws SchedulerException{
        TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
        return scheduler.checkExists(triggerKey);
    }
}
